﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms;

using AtletIS.Shared.Entities;
using AtletIS.Shared.Data;
using AtletIS.Shared.Data.aDbDataSetTableAdapters;
using System.IO;

namespace AtletIS.Shared.Helpers
{
    public static class ExtTextsHelper
    {
        private static PerformancesTableAdapter taPerformances = new PerformancesTableAdapter();
        private static DataTable dtPerformances;

        #region ExtTexts Table Schema

        /// <summary>
        ///  Vygeneruje schému tabuľky pre vrhačské disciplíny (6x pokus)
        /// </summary>
        public static DataTable CreateTableForThrows()
        {
            DataTable dtExtTexts = new DataTable();
            dtExtTexts.Columns.Add("PerformanceId", typeof(int));
            
            dtExtTexts.Columns.Add("1", typeof(string));
            dtExtTexts.Columns.Add("2", typeof(string));
            dtExtTexts.Columns.Add("3", typeof(string));
            dtExtTexts.Columns.Add("4", typeof(string));
            dtExtTexts.Columns.Add("5", typeof(string));
            dtExtTexts.Columns.Add("6", typeof(string));
            
            return dtExtTexts;
        }

        /// <summary>
        ///  Vygeneruje schému tabuľky pre horizontálne skoky (6x pokus + 6x vietor)
        /// </summary>
        public static DataTable CreateTableForHorizontalJumps()
        {
            DataTable dtExtTexts = new DataTable();
            dtExtTexts.Columns.Add("PerformanceId", typeof(int));

            dtExtTexts.Columns.Add("1", typeof(string));
            dtExtTexts.Columns.Add("2", typeof(string));
            dtExtTexts.Columns.Add("3", typeof(string));
            dtExtTexts.Columns.Add("4", typeof(string));
            dtExtTexts.Columns.Add("5", typeof(string));
            dtExtTexts.Columns.Add("6", typeof(string));

            dtExtTexts.Columns.Add("W1", typeof(string));
            dtExtTexts.Columns.Add("W2", typeof(string));
            dtExtTexts.Columns.Add("W3", typeof(string));
            dtExtTexts.Columns.Add("W4", typeof(string));
            dtExtTexts.Columns.Add("W5", typeof(string));
            dtExtTexts.Columns.Add("W6", typeof(string));

            return dtExtTexts;
        }

        /// <summary>
        ///  Vygeneruje schému tabuľky pre vertikálne skoky (Maximum, MaximumAttempt, Fails, výšky podľa Poznámky)
        /// </summary>
        public static DataTable CreateTableForVerticalJumps(DisciplineListEntity discipline)
        {
            DataTable dtExtTexts = new DataTable();
            dtExtTexts.Columns.Add("PerformanceId", typeof(int));
            dtExtTexts.Columns.Add("Maximum", typeof(int));
            dtExtTexts.Columns.Add("MaximumAttempt", typeof(int));
            dtExtTexts.Columns.Add("Fails", typeof(int));
            dtExtTexts.Columns.Add("SecondaryMaximum", typeof(int));

            string[] heights = discipline.Params.Split(',');
            foreach (string strHeight in heights)
            {
                dtExtTexts.Columns.Add(strHeight, typeof(string));
            }

            return dtExtTexts;
        }

        /// <summary>
        ///  Vygeneruje schému tabuľky pre maratóny (1x text)
        /// </summary>
        public static DataTable CreateTableForRuns(DisciplineListEntity discipline)
        {
            DataTable dtExtTexts = new DataTable();
            dtExtTexts.Columns.Add("PerformanceId", typeof(int));
            dtExtTexts.Columns.Add("Text", typeof(string));

            return dtExtTexts;
        }

        #endregion

        /// <summary>
        ///  Vygeneruje tabuľku doplňujúcich textov pre disciplínu do výsledkov
        /// </summary>
        public static DataTable ExtTextsDataTable(DisciplineListEntity discipline)
        {
            DataTable dtExtTextsOut = new DataTable();
            DataTable dtExtTextsForDiscipline = new DataTable();

            #region Throws

            if (discipline.DisciplineCode == Globals.ThrowsCode)
            {
                dtExtTextsOut = CreateTableForThrows();

                dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); // taPerformances.GetByDisciplineListId(discipline.ID);
                dtExtTextsForDiscipline = DatabaseHelper.GetExtTextsByParentDisciplineListId(discipline.ID); // taExtTexts.GetByParentDisciplineListId(discipline.ID);

                foreach (DataRow drPerformance in dtPerformances.Rows)
                {
                    dtExtTextsOut.Rows.Add();
                    DataRow drExtText = dtExtTextsOut.Rows[dtExtTextsOut.Rows.Count - 1];
                    drExtText["PerformanceId"] = Convert.ToInt32(drPerformance["ID"]);

                    DataRow[] dtExtTextsForPerformance = dtExtTextsForDiscipline.Select("PerformanceId = " + drPerformance["ID"].ToString());

                    foreach (DataRow drExtTextForPerformance in dtExtTextsForPerformance)
                    {
                        drExtText[drExtTextForPerformance["Header"].ToString()] = drExtTextForPerformance["Text1"].ToString();
                    }
                }

                return dtExtTextsOut;
            }

            #endregion

            #region Hor. jumps

            if (discipline.DisciplineCode == Globals.HorJumpCode)
            {
                dtExtTextsOut = CreateTableForHorizontalJumps();

                dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); // taPerformances.GetByDisciplineListId(discipline.ID);
                dtExtTextsForDiscipline = DatabaseHelper.GetExtTextsByParentDisciplineListId(discipline.ID); // taExtTexts.GetByParentDisciplineListId(discipline.ID);

                foreach (DataRow drPerformance in dtPerformances.Rows)
                {
                    dtExtTextsOut.Rows.Add();
                    DataRow drExtText = dtExtTextsOut.Rows[dtExtTextsOut.Rows.Count - 1];
                    drExtText["PerformanceId"] = Convert.ToInt32(drPerformance["ID"]);

                    DataRow[] dtExtTextsForPerformance = dtExtTextsForDiscipline.Select("PerformanceId = " + drPerformance["ID"].ToString(), "Header");

                    foreach (DataRow drExtTextForPerformance in dtExtTextsForPerformance)
                    {
                        drExtText[drExtTextForPerformance["Header"].ToString()] = drExtTextForPerformance["Text1"].ToString();
                        drExtText["W" + drExtTextForPerformance["Header"].ToString()] = drExtTextForPerformance["Text2"].ToString();
                    }
                }

                return dtExtTextsOut;
            }

            #endregion

            #region Ver. jumps

            if (discipline.DisciplineCode == Globals.VerJumpCode)
            {
                dtExtTextsOut = CreateTableForVerticalJumps(discipline);

                dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); // taPerformances.GetByDisciplineListId(discipline.ID);
                dtExtTextsForDiscipline = DatabaseHelper.GetExtTextsByParentDisciplineListId(discipline.ID); // taExtTexts.GetByParentDisciplineListId(discipline.ID);

                foreach (DataRow drPerformance in dtPerformances.Rows)
                {
                    dtExtTextsOut.Rows.Add();
                    DataRow drExtText = dtExtTextsOut.Rows[dtExtTextsOut.Rows.Count - 1];
                    drExtText["PerformanceId"] = Convert.ToInt32(drPerformance["ID"]);

                    DataRow[] dtExtTextsForPerformance = dtExtTextsForDiscipline.Select("PerformanceId = " + drPerformance["ID"].ToString());

                    int count = 1;
                    foreach (DataRow drExtTextForPerformance in dtExtTextsForPerformance)
                    {
                        drExtText[drExtTextForPerformance["Header"].ToString()] = drExtTextForPerformance["Text1"].ToString();
                        count += 1;
                    }
                }

                return dtExtTextsOut;
            }

            #endregion

            #region Relay

            if (discipline.Relay)
            {
                dtExtTextsOut = CreateTableForRuns(discipline);

                dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);
                dtExtTextsForDiscipline = DatabaseHelper.GetExtTextsByParentDisciplineListId(discipline.ID); // taExtTexts.GetByParentDisciplineListId(discipline.ID);

                foreach (DataRow drPerformance in dtPerformances.Rows)
                {
                    dtExtTextsOut.Rows.Add();
                    DataRow drExtText = dtExtTextsOut.Rows[dtExtTextsOut.Rows.Count - 1];
                    drExtText["PerformanceId"] = Convert.ToInt32(drPerformance["ID"]);

                    DataRow[] dtExtTextsForPerformance = dtExtTextsForDiscipline.Select("PerformanceId = " + drPerformance["ID"].ToString());

                    drExtText["Text"] = string.Empty;
                    foreach (DataRow drExtTextForPerformance in dtExtTextsForPerformance)
                    {
                        drExtText["Text"] += drExtTextForPerformance["Text1"].ToString() + ", ";
                    }
                    drExtText["Text"] = drExtText["Text"].ToString().Trim().TrimEnd(',');
                }

                return dtExtTextsOut;
            }

            #endregion

            return dtExtTextsOut;
        }

        /// <summary>
        ///  Vygeneruje NEzoradenú tabuľku doplňujúcich textov pre disciplínu
        /// </summary>
        public static DataTable ExtTextsDataTableUnsorted(DisciplineListEntity discipline)
        {
            DataTable dtExtTextsUnsorted = new DataTable();
            DataTable dtExtTextsForDiscipline = new DataTable();

            #region Throws, hor.jump

            if (discipline.DisciplineCode == Globals.ThrowsCode || discipline.DisciplineCode == Globals.HorJumpCode)
            {
                try
                {
                    if (discipline.DisciplineCode == Globals.ThrowsCode)
                        dtExtTextsUnsorted = CreateTableForThrows();

                    if (discipline.DisciplineCode == Globals.HorJumpCode)
                        dtExtTextsUnsorted = CreateTableForHorizontalJumps();

                    // Nacita pretekarov
                    dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);
                    // Nacita numericke doplnujuce texty
                    dtExtTextsForDiscipline = DatabaseHelper.GetExtTextsByParentDisciplineListIdNumeric(discipline.ID);
                    
                    foreach (DataRow dr in dtExtTextsForDiscipline.Rows)
                    {
                        dr["Text1"] = dr["Text1"].ToString().PadLeft(4, '0');
                    }

                    foreach (DataRow drPerformance in dtPerformances.Rows)
                    {
                        DataRow drExtTextUnsorted = dtExtTextsUnsorted.Rows.Add();
                        drExtTextUnsorted["PerformanceId"] = Convert.ToInt32(drPerformance["ID"]);

                        string rowFilter = "PerformanceId=" + drPerformance["ID"].ToString();
                        string sort = "Text1 DESC";

                        // Zapise vsetky numericke doplnujuce texty do riadku tabulky, zoradene MAX-min
                        int count = 1;
                        foreach (DataRow dr in dtExtTextsForDiscipline.Select(rowFilter, sort))
                        {
                            drExtTextUnsorted[count.ToString()] = dr["Text1"].ToString();
                            count += 1;
                        }
                    }
                }
                catch (Exception ex)
                {
                    ExceptionHelper.ShowErrorInfo(ex);
                }
            }

            #endregion

            #region Ver. jump

            if (discipline.DisciplineCode == Globals.VerJumpCode)
            {
                string sFilter, sOrder;

                try
                {
                    dtExtTextsUnsorted = CreateTableForVerticalJumps(discipline);

                    dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); 
                    dtExtTextsForDiscipline = DatabaseHelper.GetExtTextsByParentDisciplineListId(discipline.ID); 

                    foreach (DataRow drPerformance in dtPerformances.Rows)
                    {
                        DataRow drExtTextUnsorted = dtExtTextsUnsorted.Rows.Add(); 

                        #region Set maximum

                        string strCurrentExtText, strCurrentHeader = string.Empty;
                        string strExtTexts = string.Empty;
                        string sMaxExtText = string.Empty, sMaxHeader = string.Empty, sSecondaryMaxHeader = string.Empty;


                        sFilter = "PerformanceId = " + drPerformance["ID"].ToString() + " AND Header NOT LIKE 'R%'";
                        sOrder = "Header";
                        foreach (DataRow row in dtExtTextsForDiscipline.Select(sFilter, sOrder))
                        {
                            strCurrentExtText = row["Text1"].ToString();
                            strCurrentHeader = row["Header"].ToString();

                            drExtTextUnsorted[row["Header"].ToString()] = strCurrentExtText;
                            strExtTexts += strCurrentExtText;

                            if (strCurrentExtText.Contains('o'))
                            {
                                sMaxExtText = strCurrentExtText;
                                sMaxHeader = strCurrentHeader;
                            }
                        }

                        drExtTextUnsorted["PerformanceId"] = Convert.ToInt32(drPerformance["ID"]);
                        drExtTextUnsorted["Maximum"] = string.IsNullOrEmpty(sMaxHeader) ? 0 : Convert.ToInt32(sMaxHeader);
                        drExtTextUnsorted["MaximumAttempt"] = string.IsNullOrEmpty(sMaxHeader) ? 0 : sMaxExtText.Length;
                        
                        
                        #endregion

                        #region Set fails

                        int fails = 0;
                        strExtTexts = strExtTexts.Substring(0, strExtTexts.LastIndexOf('o') + 1);
                        char[] chars = strExtTexts.ToCharArray();
                        foreach (char c in chars)
                        {
                            if (c == 'x')
                                fails += 1;
                        }
                        drExtTextUnsorted["Fails"] = fails;

                        #endregion

                        #region Rozoskakovanie

                        /* Pridavat nove vysky s prefixom: R01_, R02_, ...
                         * do vyhodnocovacej tabulky sa prida [SecondaryMaximum] */

                        sFilter = "PerformanceId = " + drPerformance["ID"].ToString() + " AND Header LIKE 'R%'";
                        sOrder = "Header";
                        foreach (DataRow row in dtExtTextsForDiscipline.Select(sFilter, sOrder))
                        {
                            strCurrentExtText = row["Text1"].ToString();
                            strCurrentHeader = row["Header"].ToString();

                            drExtTextUnsorted[row["Header"].ToString()] = strCurrentExtText;

                            if (strCurrentExtText.Contains('o'))
                            {
                                sSecondaryMaxHeader = strCurrentHeader;
                            }
                        }
                        if (string.IsNullOrEmpty(sSecondaryMaxHeader))
                            drExtTextUnsorted["SecondaryMaximum"] = 0;
                        else
                        {
                            sSecondaryMaxHeader = sSecondaryMaxHeader.Split('_')[1];
                            drExtTextUnsorted["SecondaryMaximum"] = Convert.ToInt32(sSecondaryMaxHeader);
                        }

                        #endregion

                    }
                }
                catch (Exception ex)
                {
                    ExceptionHelper.ShowErrorInfo(ex);
                }
            }

            #endregion

            return dtExtTextsUnsorted;
        }

        /// <summary>
        ///  Vygeneruje zoradenú tabuľku doplňujúcich textov pre disciplínu
        /// </summary>
        public static DataRow[] ExtTextsDataTableSorted(DisciplineListEntity discipline)
        {
            DataTable dtExtTextUnsortedLocal = ExtTextsDataTableUnsorted(discipline);

            switch (discipline.DisciplineCode)
            { 
                case Globals.ThrowsCode:
                case Globals.HorJumpCode:
                    return dtExtTextUnsortedLocal.Select(null, "1 DESC, 2 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC");
                   
                case Globals.VerJumpCode:
                    return dtExtTextUnsortedLocal.Select(null, "Maximum DESC, MaximumAttempt ASC, Fails ASC, SecondaryMaximum DESC");
                
                default:
                    return null;
            }
        }

        public static bool ValidateExtText(string extText)
        {
            if (string.IsNullOrEmpty(extText))
                return true;

            if (ValidationHelper.IsInt32(extText))
            {
                if (Convert.ToInt32(extText) >= 0)
                    return true;
            }

            if (extText == "x" | extText == "-" | extText == "o")
                return true;

            if (extText == "xo" | extText == "xx" | extText == "x-")
                return true;

            if (extText == "xxo" | extText == "xxx" | extText == "xx-")
                return true;

            return false;
        }

        /// <summary>
        ///  Update Performances podľa doplňujúcich textov (kódy 3,4,5) - výkony, poradie, kód
        /// </summary>
        public static DataRow[] UpdatePerformances(DisciplineListEntity discipline)
        {
            // Reset discipline
            dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);
            foreach (DataRow drPerformance in dtPerformances.Rows)
            {
                drPerformance["Rank"] = 0;
                drPerformance["Result"] = 0;
                drPerformance["Modified"] = DateTime.Now;
            }
            taPerformances.Update((aDbDataSet.PerformancesDataTable)dtPerformances);

            // Get sorted table
            DataRow[] aExtTexts = ExtTextsDataTableSorted(discipline);

            #region Throws / Hor. jumps

            if (discipline.DisciplineCode == Globals.ThrowsCode
                | discipline.DisciplineCode == Globals.HorJumpCode)
            {
                int rank = 1, prevRank = 0;
                for (int i = 0; i < aExtTexts.Count(); i++)
                {
                    if (aExtTexts[i]["1"].ToString() != string.Empty)
                    {
                        int perfId = Convert.ToInt32(aExtTexts[i]["PerformanceId"]);
                        dtPerformances = DatabaseHelper.GetPerformancesById(perfId); // taPerformances.GetById(perfId);
                        if (Convert.ToInt32(dtPerformances.Rows[0]["Code"]) == 0)
                        {
                            dtPerformances.Rows[0]["Rank"] = rank;
                            dtPerformances.Rows[0]["Result"] = aExtTexts[i]["1"];

                            // Pri zhode da rovnake poradie
                            if (i > 0)
                            {
                                if (aExtTexts[i]["1"].ToString() == aExtTexts[i - 1]["1"].ToString()
                                    & aExtTexts[i]["2"].ToString() == aExtTexts[i - 1]["2"].ToString()
                                    & aExtTexts[i]["3"].ToString() == aExtTexts[i - 1]["3"].ToString()
                                    & aExtTexts[i]["4"].ToString() == aExtTexts[i - 1]["4"].ToString()
                                    & aExtTexts[i]["5"].ToString() == aExtTexts[i - 1]["5"].ToString()
                                    & aExtTexts[i]["6"].ToString() == aExtTexts[i - 1]["6"].ToString())
                                {
                                    dtPerformances.Rows[0]["Rank"] = prevRank;
                                }
                            }

                            // Update
                            taPerformances.Update(dtPerformances.Rows[0]);
                            
                            rank += 1;
                            prevRank = Convert.ToInt32(dtPerformances.Rows[0]["Rank"]);
                        }
                        
                    }
                }
            }

            #endregion

            #region Ver. jumps

            if (discipline.DisciplineCode == Globals.VerJumpCode)
            {
                int prevRank = 0;
                for (int i = 0; i < aExtTexts.Count(); i++)
                {
                    if (aExtTexts[i]["Maximum"].ToString() != "0")
                    {
                        int perfId = Convert.ToInt32(aExtTexts[i]["PerformanceId"]);

                        dtPerformances = DatabaseHelper.GetPerformancesById(perfId);
                        dtPerformances.Rows[0]["Rank"] = i + 1;
                        if (aExtTexts[i]["Maximum"] == DBNull.Value)
                            dtPerformances.Rows[0]["Result"] = 0;
                        else
                            dtPerformances.Rows[0]["Result"] = aExtTexts[i]["Maximum"];

                        // Pri zhode da rovnake poradie
                        if (i > 0)
                        {
                            if (aExtTexts[i]["SecondaryMaximum"].ToString() == aExtTexts[i - 1]["SecondaryMaximum"].ToString()
                                & aExtTexts[i]["Maximum"].ToString() == aExtTexts[i - 1]["Maximum"].ToString()
                                & aExtTexts[i]["MaximumAttempt"].ToString() == aExtTexts[i - 1]["MaximumAttempt"].ToString()
                                & aExtTexts[i]["Fails"].ToString() == aExtTexts[i - 1]["Fails"].ToString())
                            {
                                dtPerformances.Rows[0]["Rank"] = prevRank;
                            }
                        }

                        taPerformances.Update(dtPerformances.Rows[0]);
                        prevRank = Convert.ToInt32(dtPerformances.Rows[0]["Rank"]);
                    }
                }
            }

            #endregion

            return aExtTexts;
        }

        public static void PrintRelayTable(DisciplineListEntity discipline, StreamWriter sw)
        {
            DataTable dtExtTextsForPerfs = ExtTextsHelper.ExtTextsDataTable(discipline);
            if (dtExtTextsForPerfs != null && dtExtTextsForPerfs.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");
                sw.WriteLine("<table class=\"extra\">");

                foreach (DataRow dr in dtPerformances.Select("Rank > 0 OR (Rank = 0 AND Code <> 0)", "Code, Rank"))
                {
                    DataRow[] drExtText = dtExtTextsForPerfs.Select("PerformanceId = " + dr["ID"]);

                    try
                    {
                        if (drExtText[0]["Text"].ToString() != string.Empty)
                        {
                            sw.WriteLine("<tr>");
                            sw.WriteLine("  <td width=\"20\"></td>");
                            sw.WriteLine("  <td>" + PrintHelper.PrintRelayName(dr, Globals.ActiveCompetition.ClubsCountries) + "</td>");
                            sw.WriteLine("  <td>" + drExtText[0]["Text"].ToString() + "</td>");
                            sw.WriteLine("</tr>");
                        }
                    }
                    catch { }
                }

                foreach (DataRow dr in dtPerformances.Select("Rank = 0 AND Code = 0", "Code, Rank"))
                {
                    DataRow[] drExtText = dtExtTextsForPerfs.Select("PerformanceId = " + dr["ID"]);

                    try
                    {
                        if (drExtText[0]["Text"].ToString() != string.Empty)
                        {
                            sw.WriteLine("<tr>");
                            sw.WriteLine("  <td width=\"20\"></td>");
                            sw.WriteLine("  <td>" + PrintHelper.PrintRelayName(dr, Globals.ActiveCompetition.ClubsCountries) + "</td>");
                            sw.WriteLine("  <td>" + drExtText[0]["Text"].ToString() + "</td>");
                            sw.WriteLine("</tr>");
                        }
                    }
                    catch { }
                }

                sw.WriteLine("</table>");
            }
        }





    }
}
